package cn.zkcloud.servlet;

import javassist.bytecode.ClassFile;
import org.apache.log4j.Logger;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * @Author zk
 * @Date 2017/7/8.
 * @Email zkdcloud_cn@163.com
 */
public class ScanResolver {

    private static Logger logger = Logger.getLogger(ScanResolver.class);

    private static ClassLoader clazzLoader = Thread.currentThread().getContextClassLoader();

    private static List<String> rootPaths = new ArrayList<>();

    private Set<URL> urlSet = new HashSet<>();

    static {
        try {
            Enumeration<URL> urls = clazzLoader.getResources("");
            while(urls.hasMoreElements()){
                String path = urls.nextElement().getPath();
                if(path.startsWith("/"))
                    path = path.substring(1);
                rootPaths.add(path.replace("/","\\"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 仅扫描该工程中的class文件,不包括jar中的class
     */
    private void initScan() {
        Set<URL> clazzUrls = new HashSet<>();

        try {
            Enumeration<URL> urls = clazzLoader.getResources("");
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                File dirFile = new File(url.getPath());
                if (url.getProtocol().equals("file") && dirFile.isDirectory()) {
                    clazzUrls.addAll(reScanDir(dirFile));
                }
            }

            for (URL url : clazzUrls) {
                DataInputStream dataInputStream = new DataInputStream(url.openStream());
                ClassFile clazzFile = new ClassFile(dataInputStream);
            }
        } catch (IOException e) {
            logger.error(e.getStackTrace());
        }
    }

    /**
     * 循环扫描文件夹
     *
     * @param dirFile
     */
    public Set<URL> reScanDir(File dirFile) {
        for (File file : dirFile.listFiles()) {
            if (file.isDirectory()) {
                reScanDir(file);
            } else if (file.getPath().endsWith(".class")) {
                urlSet.add(getUrlBylocationPath(file.getPath()));
            }
        }
        return urlSet;
    }

    /** 根据位置返回该资源
     *
     * @param path
     * @return
     */
    public URL getUrlBylocationPath(String path){
        for(String root : rootPaths){
            if(path.startsWith(root)){
                return clazzLoader.getResource(path.substring(root.length()));
            }
        }
        return null;
    }
}
